import qs from 'qs'
import { localStorageMethods } from '../common/storage'
import { AUTHORIZATION_TOKEN, ID_TOKEN, REFRESH_TOKEN } from '../constant'
import { getQueryObject, removeURLParameter } from './utils'
import { getToken, getUserInfo, ssoLogin, verifyLogin } from '../apis/login'
import { useUserStore } from '../store/user'
import pinia from '../store'
import { useRouterStore } from '../store/router'
import { isEmpty, isNotEmpty } from '../utils/common'

const userStore = useUserStore(pinia)
const ssoLoginUrl = (import.meta as any).env.VITE_ssoLoginUrl
const ssoDomain = (import.meta as any).env.VITE_ssoDomain
localStorageMethods.setLocalStorage('loginRetryTime', '3')
export const isLocalLogin = () => ssoDomain === 'localhost'

export const navigation2Login = () => {
  if (isLocalLogin()) {
    userStore.hasLogin = false
  } else {
    _ssoLogin()
  }
}
const _ssoLogin = () => {
  let redirectUri = ssoDomain
  if (isEmpty(redirectUri)) {
    const url = window.location.href.split('://')[1]
    const http = window.location.href.split(url)[0]
    redirectUri = http + url.split('?')[0].split('/')[0] + '/sso'
  }
  const targetUrl = encodeURIComponent(window.location.href)
  window.location.href = ssoLoginUrl + '&redirect_uri=' + redirectUri + '&target_url=' + targetUrl
}

const _executeLogin = (token: string) => {
  if (isLocalLogin()) {
    return new Promise(() => localStorageMethods.setLocalStorage(AUTHORIZATION_TOKEN, token))
  } else {
    if (isNotEmpty(userStore.getIdToken)) {
      return ssoLogin(userStore.getIdToken)
        .then(
          (res) => {
            const payload = res.payload
            if (payload && payload.accessToken) {
              userStore.setInfo(payload)
              localStorageMethods.setLocalStorage(AUTHORIZATION_TOKEN, payload.accessToken)
              localStorageMethods.setLocalStorage(REFRESH_TOKEN, payload.refreshToken)
              userStore.hasLogin = true
              localStorageMethods.setLocalStorage('loginRetryTime', '3')
            }
            return 1
          },
          (err) => {
            if (err && err.payload && err.payload.ssoLoginUrl) {
              console.log(err.payload.ssoLoginUrl)
              const retryTimes = localStorageMethods.getLocalStorage('loginRetryTime')
              if (Number(retryTimes) - 1 >= 0) {
                localStorageMethods.setLocalStorage('loginRetryTime', '' + (Number(retryTimes) - 1))
                navigation2Login()
              }
            } else {
              console.log('token验证失败')
              throw new Error(err)
            }
          }
        )
        .catch((err) => {
          console.log('服务器状态异常')
          throw new Error(err)
        })
    } else {
      navigation2Login()
    }
  }
}
export const checkLoginState = async () => {
  handleSsoUrl()
  const token = localStorageMethods.getLocalStorage(AUTHORIZATION_TOKEN)
  if (token) {
    return verifyToken(token)
  } else {
    return generateToken()
  }
}
const handleSsoUrl = () => {
  const queryObject = getQueryObject(window.location.href)
  if (isNotEmpty(queryObject)) {
    if (isNotEmpty(queryObject.target_url)) {
      const targetUrl = queryObject.target_url
      delete queryObject.target_url
      window.location.href = targetUrl + '?' + qs.stringify(queryObject, { arrayFormat: 'repeat' })
    } else if (isNotEmpty(queryObject.id_token)) {
      userStore.setIdToken(<string>queryObject.id_token).then(() => {
        window.location.href = removeURLParameter(window.location.href, ID_TOKEN)
      })
    }
  }
}
const verifyToken = async (localStorageToken: string) => {
  return await verifyLogin(localStorageToken).then((res) => {
    const result = res.payload
    if (!+result) {
      getToken().then((getTokenRes) => {
        const { token } = getTokenRes.payload
        if (isLocalLogin()) {
          userStore.hasLogin = false
          return localStorageMethods.setLocalStorage(AUTHORIZATION_TOKEN, token)
        } else {
          return _executeLogin(token)?.then(() => {
            return afterLogin()
          })
        }
      })
    } else {
      userStore.hasLogin = true
      return afterLogin()
    }
  })
}
const generateToken = async () => {
  return await getToken().then((getTokenRes) => {
    const { token } = getTokenRes.payload
    if (isLocalLogin()) {
      userStore.hasLogin = false
      return localStorageMethods.setLocalStorage(AUTHORIZATION_TOKEN, token)
    } else {
      return _executeLogin(token)?.then(() => {
        return afterLogin()
      })
    }
  })
}
export const afterLogin = async () => {
  return getUserInfo()
    .then((res) => {
      const data = res.payload
      const userStore = useUserStore()
      userStore.setInfo(data)
      userStore.showLogin = false
    })
    .then(useRouterStore().getAfterLoginHandler)
}
